#include "lexer.h"

Lexer::Lexer(string input_file_name) : curr_char_(0), last_char_(0)
{
    fin_.open(input_file_name);
    if (!fin_.is_open()) {
        cout << "LEXER Forest failed to open input file " << input_file_name << " in lexer" << endl;
    }
    fin_ >> noskipws;
}

Lexer::~Lexer()
{
    fin_.close();
}

bool Lexer::UpdateChar()
{
    last_char_ = curr_char_;
    if (fin_ >> curr_char_) {
        return true;
    } else {
        return false;
    }
}

Token* Lexer::GetNextToken()
{
    ostringstream oss;
   if (curr_char_ == 0) {
        fin_ >> curr_char_;
        last_char_ = curr_char_;
    }
    if (curr_char_ == EOF) {
        return new EndToken();
    }
    if (isalpha(curr_char_)) {
        oss << curr_char_;
        while(!fin_.eof()) {
            UpdateChar();
            cout << "Get variable char " << static_cast<int>(curr_char_) << endl;
            if (!isalpha(curr_char_)) {
                cout << "2 Not alpha " << oss.str() << ", curr char " << curr_char_ << endl;
                if (oss.str() == KEYWORD_PRINT) {
                    return new PrintToken();
                }
                return new VarToken(oss.str());
            } else {
                oss << curr_char_;
            }
        }
    } else if (isdigit(curr_char_)) {
        ostringstream oss;
        oss << curr_char_;
        while(!fin_.eof()) {
            UpdateChar();
            if (!isdigit(curr_char_)) {
                return new IntToken(atoi(oss.str().c_str()));
            } else {
                oss << curr_char_;
            }
        }
    } else if (isspace(curr_char_)) {
        if (!UpdateChar()) {
            curr_char_ = EOF;
        }
        return GetNextToken();
    } else if (curr_char_ == ';') {
        if (!UpdateChar()) {
            curr_char_ = EOF;
        }
        return new SemiToken();
    } else if (curr_char_ == '+') {
        fin_ >> curr_char_;
        return new AddToken();
    }else if (curr_char_ == '-') {
        fin_ >> curr_char_;
        return new MinusToken();
    } else if (curr_char_ == '*') {
        fin_ >> curr_char_;
        return new MulToken();
    } else if (curr_char_ == '/') {
        fin_ >> curr_char_;
        return new DivToken();
    } else if (curr_char_ == '=') {
        fin_ >> curr_char_;
        return new AssignToken();
    } else {
        return new EndToken();
    }
}